package com.siecom.framework.module;

import android.graphics.Bitmap;
import android.util.Base64;
import android.util.Log;

import com.bank.GuiZhou.ConstDefine;
import com.siecom.framework.appinterface.APDU_RESP;
import com.siecom.framework.channel.ChannelInstance;
import com.siecom.framework.constconfig.Config;
import com.siecom.framework.listen.FingerPrintListen;
import com.siecom.tools.ByteTool;
import com.siecom.tools.FingerUnit;
import com.siecom.tools.LogUtil;
import com.siecom.tools.SingletonThreadPool;

import java.util.concurrent.ExecutorService;

/**
 * Created by zhq on 2015/12/10.
 */
public class FingerPrintModule extends CommonModule {
	private final String TAG = "FingerPrintModule";
	public int slot[] = new int[20];
	private FingerPrintListen callback;
	private static FingerPrintModule module = null;
	private FingerPrintThread Finger_Thread = null;
//	private RegistrationFingerThread Registration_Finger_Thread = null;
	private ReadWrite mReadWrite = null;
	private static int fingerType = 1;
	public static final int OPCODE_GETIMAGE_TEST = 7;
	private byte imageData[] = new byte[40000];
	private Bitmap fingerPrintBMP = null;
	private static ExecutorService threadPool = SingletonThreadPool
			.getInstance();
	private boolean lockFlag = false;

	private FingerPrintModule() {

	}

	@Override
	public void closeModule(boolean isConnected) {
		Log.e(TAG, "closeModule");
		if(null != mReadWrite && !mReadWrite.isThreadFinished()){
			mReadWrite.setFlag(false);
		}
		if (null != Finger_Thread && !Finger_Thread.isThreadFinished()) {
			Finger_Thread.setFlag(false);
//			while (!Finger_Thread.isThreadFinished()) {
//				try {
//					Thread.sleep(10);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//			};
//			Finger_Thread = null;
		}
		if (isConnected) {
			lockFlag = true;
			//api.TCD_Close();
			lockFlag = false;
		}
	}

	@Override
	public boolean isFinish() {
		if (Finger_Thread == null || Finger_Thread.isThreadFinished()) {
			return true;
		} else {
			return false;
		}
	}

//	public void startRegistration(final int printType){
//		Log.e(tag, "startRead");
//		Runnable r = new Runnable() {
//			@Override
//			public void run() {
//				if (null != Registration_Finger_Thread && !Registration_Finger_Thread.isThreadFinished()) {
//					Registration_Finger_Thread.setFlag(false);
//					while (!Registration_Finger_Thread.isThreadFinished()) {
//						try {
//							Thread.sleep(10);
//						} catch (InterruptedException e) {
//							e.printStackTrace();
//						}
//					}
//					Registration_Finger_Thread = null;
//				}
//				while (lockFlag) {
//					try {
//						Thread.sleep(1);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
//				}
//				fingerType = printType;
//				Registration_Finger_Thread = new RegistrationFingerThread();
//				Registration_Finger_Thread.start();
//				Log.e(tag, "start!!!!");
//			}
//		};
//		threadPool.submit(r);
//
//	}
	public void startRead(final int printType) {
		Log.e(TAG, "startRead");
		Runnable r = new Runnable() {
			@Override
			public void run() {
				if (null != Finger_Thread && !Finger_Thread.isThreadFinished()) {
					Finger_Thread.setFlag(false);
					while (!Finger_Thread.isThreadFinished()) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					Finger_Thread = null;
				}
				while (lockFlag) {
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				fingerType = printType;
				Finger_Thread = new FingerPrintThread();
				Finger_Thread.start();
				Log.e(TAG, "start!!!!");
			}
		};
		threadPool.submit(r);
	}

	public void setCallback(FingerPrintListen callback) {
		this.callback = callback;
	}

	public static FingerPrintModule getInstance() {
		if (module == null) {
			module = new FingerPrintModule();
		}
		return module;
	}

	public void fingerImg() {
		Log.e(TAG, "startRead");
		Runnable r = new Runnable() {
			@Override
			public void run() {
				if (null != mReadWrite && !mReadWrite.isThreadFinished()) {
					while (!mReadWrite.isThreadFinished()) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					mReadWrite = null;
				}
				while (lockFlag) {
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				mReadWrite = new ReadWrite(0);
				mReadWrite.start();
				Log.e(TAG, "start!!!!");
			}
		};
		threadPool.submit(r);
	}

	@Override
	public int OpenModule() {
		int ret = 0;

		for(int p = 0; p < 5; ++p) {
			ret = api.TCD_Open();
			if(ret == 0) {
				break;
			}

			api.TCD_Close();
			ChannelInstance.resetChannel();
		}

		return ret;
	}
	public static String FINGER_TYPE_STR = "";
	private class ReadWrite extends Thread {
		private int mOpCode;
		int ret;
		private boolean isThreadFinished = false;
		private boolean runFlag = true;
		public boolean isThreadFinished() {
			return isThreadFinished;
		}

		public void setFlag(boolean flag) {
			runFlag = flag;
		}

		public ReadWrite(int OpCode) {
			runFlag = true;
			mOpCode = OpCode;
		}

		@Override
		public void run() {
			synchronized (this) {
				callback.onStart();
				isThreadFinished = false;
				for (int i = 0; i < 10; i++) {
					int iRetCode = api.TCD_Open();
					if (iRetCode == 0) {
						break;
					}
				}
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
				byte packIndex = 0;
				byte[] finishFlag = new byte[1];
				byte dataOut[] = new byte[1024];
				int[] lenOut = new int[1];
				int dataIndex = 0;
				finishFlag[0] = 1;
				long now  =0L;

				byte[] code = new byte[128];
				byte[] type = new byte[1];
				int[]  len = new int[1];
				int fret = api.getFingerVersion(type,code,len);
				int FingerType = -1;
				if(fret == 0  ){
					if(type[0] == 0x04){
						FingerType = 4; //中正SM-2B_FM-205B
					}
					if(type[0] == 0x00){
						FingerType = 0; //中正
						FINGER_TYPE_STR = "ZZ";
					}
					if(type[0] == 0x01){
						FingerType = 1; //天诚盛业
						FINGER_TYPE_STR = "TC";
					}
					if(type[0] == 0x02){
						FingerType = 2; //维尔
						FINGER_TYPE_STR = "WEL";
					}
				}

				//-----------------读指纹特征码-----------------------------
				APDU_RESP ApduResp_TCD = new APDU_RESP();
				while ( runFlag){
					ret = api.TCD_Read_Test(ApduResp_TCD);
					if(ret == 0){
						String strInfo = "";
						byte[] fingerByte = new byte[ApduResp_TCD.LenOut];
						try {
							System.arraycopy(ApduResp_TCD.DataOut, 0,
									fingerByte, 0, ApduResp_TCD.LenOut);
							Log.e("fingerCode:",
									ByteTool.byte2hex(fingerByte));
							if (fingerType == Config.WELL_FINGER) {
								strInfo = FingerUnit
										.parseWellcom(fingerByte);
							} else if (fingerType == Config.SHENGYE_FINGER) {
								strInfo = Base64.encodeToString(fingerByte,
										Base64.NO_WRAP);
							} else {
								strInfo = Base64.encodeToString(fingerByte,
										Base64.NO_WRAP);
							}
						} catch (ArrayIndexOutOfBoundsException e) {
							continue;
						}
						LogUtil.e(TAG,"FingerPrintInfo == " + strInfo);
						callback.onRead(strInfo);
						callback.onGetImgSucc(null);
						break;
					}
				}

				//--------------------------------------------------------
//				while (runFlag && finishFlag[0] == 1) {
//					if(packIndex==1){
////						callback.onStart();
//						now = System.currentTimeMillis();
//					}
//					for (int i = 0; i < 2; i++) {
//						if(FingerType == 4){
//							ret = api.Lib_FpGetImgZZSM205(packIndex,finishFlag,dataOut,lenOut);
//						}else {
//							ret = api.Lib_FpGetImg(packIndex, finishFlag, dataOut, lenOut);
//						}
//						Log.e(TAG, "Lib_FpGetImgT:" + ret);
//						if (ret == 0) {
//							break;
//						}
//					}
//					Log.e(TAG,
//							"finishFlag:"
//									+ ByteTool.byteToHexString(finishFlag[0]));
//					if (ret != 0) {
//						Log.e(TAG, "Lib_FpGetImg fail, ret = " + ret);
//						callback.onFail(ret, "获取图像失败");
//						isThreadFinished = true;
//						Log.e(TAG, "1.获取图像失败" + ret);
//						api.TCD_Close(); //关闭指纹
//						return;
//					} else if (finishFlag[0] == 0) { // 0 接收完毕  1 继续接收下一包
//						System.arraycopy(dataOut, 0, imageData, dataIndex,
//								lenOut[0]);
//						dataIndex += lenOut[0];
//						if(FingerType == 4){ //需要将压缩数据展开
//							byte[] fingerByte = new byte[dataIndex * 2];
//							for(int i = 0; i < dataIndex; i++){
//								fingerByte[i*2] = (byte) (imageData[i] & 0xF0);
//								fingerByte[i*2 + 1] = (byte) ((imageData[i] & 0x0F) << 4);
//							}
//							fingerPrintBMP = api.CreateBMP(fingerByte, dataIndex * 2, "/sdcard/", "FingerPrint.bmp");
//							LogUtil.e(TAG,"fingerByte length ==" + fingerByte.length);
//						}else {
//							fingerPrintBMP = api.CreateBMP(imageData, dataIndex, "/sdcard/", "FingerPrint.bmp");
//						}
//
//						Log.e(TAG, "Lib_FpGetImg  totallen = " + dataIndex);
//						long finish = System.currentTimeMillis();
//						if (fingerPrintBMP != null) {
//							Log.e(TAG, "ImguseTime:" + (finish - now) + "ms");
//							Log.e(TAG, "getWidth:" + fingerPrintBMP.getWidth() + "----getHeight ==" +fingerPrintBMP.getHeight());
//							callback.onGetImgSucc(fingerPrintBMP);
//						} else {
//							callback.onFail(ret, "获取图像失败");
//						}
//						Log.e(TAG, "接收完毕 ret = " + ret);
//						break;
//					} else {
//						packIndex++;
//						System.arraycopy(dataOut, 0, imageData, dataIndex,
//								lenOut[0]);
//						dataIndex += lenOut[0];
//						Log.e(TAG, "Lib_FpGetImg  packIndex = " + packIndex);
//						Log.e(TAG, "Lib_FpGetImg  currentLen = " + dataIndex);
//						Log.e(TAG, "3 go on");
//						callback.onGetImgProgress(dataIndex);
//						// callback.onGetImgProgress((dataIndex*100/30400));
//					}
//				}
				ret = api.TCD_Close();
				isThreadFinished = true;
			}
			// setCancle();
		}
	}


//	public class RegistrationFingerThread extends Thread {
//		private boolean runFlag = true;
//		private boolean m_bThreadFinished = false;
//
//		public boolean isThreadFinished() {
//			return m_bThreadFinished;
//		}
//
//		public RegistrationFingerThread() {
//			runFlag = true;
//		}
//
//		public void setFlag(boolean flag) {
//			runFlag = flag;
//		}
//
//		@Override
//		public void run() {
//			int ret = 1;
//			ret = OpenModule();
//			if (ret != 0) {
//				if (callback != null) {
//					callback.onFail(-884, "指纹模块打开失败");
//				}
//				api.IDCard_Close();
//				m_bThreadFinished = true;
//				return;
//			}
//			if (callback != null) {
//				callback.onStart();
//			}
//			try {
//				synchronized (this) {
//					while (runFlag) {
//						try {
//							Thread.sleep(1000);
//						} catch (InterruptedException e) {
//							e.printStackTrace();
//						}
//						APDU_RESP ApduResp_TCD = new APDU_RESP();
//						ret = api.Registration_Read_Test(ApduResp_TCD);
//						//Log.e("RecvSendLog","结果返回"+ret);
//						if (0 == ret) {
//							String strInfo = "";
//							byte[] fingerByte = new byte[ApduResp_TCD.LenOut];
//							try {
//								System.arraycopy(ApduResp_TCD.DataOut, 0,
//										fingerByte, 0, ApduResp_TCD.LenOut);
//								Log.e("fingerCode:",
//										ByteTool.byte2hex(fingerByte));
//								if (fingerType == Config.WELL_FINGER) {
//									strInfo = FingerUnit
//											.parseWellcom(fingerByte);
//								} else if (fingerType == Config.SHENGYE_FINGER) {
//									strInfo = Base64.encodeToString(fingerByte,
//											Base64.NO_WRAP);
//								} else {
//									strInfo = Base64.encodeToString(fingerByte,
//											Base64.NO_WRAP);
//								}
//							} catch (ArrayIndexOutOfBoundsException e) {
//								continue;
//							}
//							callback.onRead(strInfo);
//							runFlag = false;
//							break;
//						} else {
//							runFlag = false;
//							callback.onFail(ret, "未读取到指纹");
//						}
//					}
//				}
//			} finally {
//				m_bThreadFinished = true;
//			}
//
//		}
//
//	}

	public class FingerPrintThread extends Thread {
		private boolean runFlag = true;
		private boolean m_bThreadFinished = false;

		public boolean isThreadFinished() {
			return m_bThreadFinished;
		}

		public FingerPrintThread() {
			runFlag = true;
		}

		public void setFlag(boolean flag) {
			runFlag = flag;
		}

		@Override
		public void run() {
			int ret = 1;
//			ret = OpenModule();
//			if (ret != 0) {
//				if (callback != null) {
//					callback.onFail(-884, "指纹模块打开失败");
//				}
//				api.IDCard_Close();
//				m_bThreadFinished = true;
//				return;
//			}
			if (callback != null) {
				callback.onStart();
			}
			try {
				synchronized (this) {
					while (runFlag) {
						try {
							ret = api.TCD_Open();
							if (ret != 0) {
								if (callback != null) {
									callback.onFail(-884, "指纹模块打开失败");
								}
								api.IDCard_Close();
								m_bThreadFinished = true;
								return;
							}
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						APDU_RESP ApduResp_TCD = new APDU_RESP();
						ret = api.TCD_Read_Test(ApduResp_TCD);
						if (0 == ret) {
							String strInfo = "";
							byte[] fingerByte = new byte[ApduResp_TCD.LenOut];
							try {
								System.arraycopy(ApduResp_TCD.DataOut, 0,
										fingerByte, 0, ApduResp_TCD.LenOut);
								Log.e("fingerCode:",
										ByteTool.byte2hex(fingerByte));
								if (fingerType == Config.WELL_FINGER) {
									strInfo = FingerUnit
											.parseWellcom(fingerByte);
								} else if (fingerType == Config.SHENGYE_FINGER) {
									strInfo = Base64.encodeToString(fingerByte,
											Base64.NO_WRAP);
								} else {
									strInfo = Base64.encodeToString(fingerByte,
											Base64.NO_WRAP);
								}
							} catch (ArrayIndexOutOfBoundsException e) {
								continue;
							}
							callback.onRead(strInfo);
							runFlag = false;
							break;
						} else {
							api.TCD_Close();
							// callback.onFail(ret, "未读取到指纹");
						}
					}
				}
			} finally {
				m_bThreadFinished = true;
				api.TCD_Close(); //
			}

		}

	}

}
